package com.rock.sys.global;

import java.util.ArrayList;
import java.util.List;

import com.eova.aop.eova.EovaContext;
import com.eova.aop.eova.EovaIntercept;
import com.eova.config.EovaConst;
import com.eova.model.MetaField;
import com.eova.model.User;
import com.jfinal.plugin.activerecord.Db;
import com.rock.sys.config.RockConst;

import cn.hutool.core.util.StrUtil;

/**
 * ROCK-APP框架全局业务拦截器，处理多租户及app隔离
 * 
 * @author jadison
 *
 */
public class RockGlobalIntercept extends EovaIntercept {

	// -- > 命中 Grid,Tree,TreeGrid的查询,导出功能
	@Override
	public String filterQuery(EovaContext ec) throws Exception {
		System.out.println("启动Rock全局Query数据过滤");

		// 当前用户，从session中取，兼容pc及app
		User user = ec.ctrl.getSessionAttr(EovaConst.USER);
		// 当前APP_ID，从attribute中取，PC端时为空，移动端时才有值
		String appId = ec.ctrl.getAttr(RockConst.ATTR_LOGINED_APP_ID);

		String userId = "";
		// 租户ID
		String tenantId = "";

		// 如果用户信息不为空时（APP用户未绑定时则user为空）
		if (user != null) {
			// 超级管理员不做任何数据过滤限制
			if (user.isAdmin()) {
				System.out.println("超级管理员，不进行任何数据过滤");
				return "";
			}
			userId = user.getStr("id");
			// 租户ID
			tenantId = Db.queryStr("select tenant_id from t_user where id=?", userId);
			System.out.println("当前登录用户所属租户ID：" + tenantId);
		} else if (StrUtil.isNotBlank(appId)) {
			// 当APP用户未绑定时则user为空，当前上下文的tenantId置成APP归属的租户
			tenantId = Db.queryStr("select t.id from t_s_app a,t_s_tenant t where a.id=? and a.tenant_id=t.id", appId);
			System.out.println("当前APP用户未绑定，APP所属租户ID：" + tenantId);
			// 不再取用户信息
			// user = User.dao.findById(aUserId);
		} else {
			// 既没有用户信息，也没有APPID信息，请求异常
			System.out.println("既没有用户信息，也没有APPID信息，请求异常");
			return "";
		}

		String rfilter = "";
		for (MetaField f : ec.object.getFields()) {

			// 叠加租户条件
			if (f.getEn().equals("tenant_id")) {
				rfilter += " and tenant_id='" + tenantId + "'";
			}

			// 叠加APP条件，appid有值时，取当前app或未分配app的所有数据
			if (StrUtil.isNotBlank(appId)) {
				if (f.getEn().equals("app_id")) {
					rfilter += " and (app_id='" + appId + "' or app_id is null)";
				}
			}
		}
		return rfilter;
	}

	// -- > 命中Find,Combo,ComboTree 的表达式条件过滤
	@Override
	public List<String> filterExp(EovaContext ec) throws Exception {
		System.out.println("启动Rock全局Exp过滤");
		//条件列表
		List<String> conList = new ArrayList<String>();
		
		User user = ec.ctrl.getSessionAttr(EovaConst.USER);
		// 当前APP，从attribute中取，PC端时为空，移动端时才有值
		String appId = ec.ctrl.getAttr(RockConst.ATTR_LOGINED_APP_ID);

		String userId = "";
		// 租户ID
		String tenantId = "";

		// 如果用户信息不为空时（APP用户未绑定时则user为空）
		if (user != null) {
			// 超级管理员不做任何数据过滤限制
			if (user.isAdmin()) {
				System.out.println("超级管理员，不进行任何表达式数据过滤");
				return conList;
			}

			userId = user.getStr("id");
			// 租户ID
			tenantId = Db.queryStr("select tenant_id from t_user where id=?", userId);
			System.out.println("当前登录用户所属租户ID：" + tenantId);
		} else if (StrUtil.isNotBlank(appId)) {
			// 当APP用户未绑定时则user为空，当前上下文的tenantId置成APP归属的租户
			tenantId = Db.queryStr("select t.id from t_s_app a,t_s_tenant t where a.id=? and a.tenant_id=t.id", appId);
			System.out.println("当前APP用户未绑定，APP所属租户ID：" + tenantId);
			// 不再取用户信息
			// user = User.dao.findById(aUserId);
		}

		// 测试表达式引用的表是否有tenant_id字段，如果有，则限制只显示当前租户，否则不限制
		String fromSql = ec.exp.from;
		String tableName = fromSql.substring(fromSql.indexOf("from") + 5);

		// 兼容带别名的表达式
		if (tableName.contains(" ")) {
			tableName = tableName.substring(0, tableName.indexOf(" "));
		}
		String testSql = "select 1 from information_schema.columns where table_name=? and column_name ='tenant_id'";
		Integer res = Db.queryInt(testSql, tableName);

		// 不为空，说明引用表存在tenant_id字段，限制只显示当前租户
		if (res != null) {
			conList.add(" and tenant_id='" + tenantId + "'");
		}

		return conList;
	}

}
